#include "global.h"

// Global process structures
Process			processes[NUM_PROCS];
Process*		running;
ProcessQueue	readyQueue;
ProcessQueue	freeQueue;
ProcessQueue	sleepQueue;
int				processSize = sizeof(Process);
Pipe 			pipes[NUM_PIPES];
File 			fileEntries[NUM_FILE_DESC];
int				inkmode = 1;

char processNames[NUM_PROCS][15] = { "Sun", "Mercury", "Venus", "Earth",
	"Mars", "Jupiter", "Saturn", "Uranus", "Neptune", "Pluto" };

// These are screams processes make when they die
char deathCries[4][30] = {
		"Oh! You are killing me ...",
		"Oh! I am dying ...........",
		"Oh! I am a goner .........",
		"Bye! Bye! World .........." };

// The main entry point of the kernel
void initializeProcesses();
void main()
{
	initializeVideoDriver();
	printf("Welcome to the Simple OS!\n");
	printf("\n  * Initializing process structures... ");
	initializeProcesses();
	printf("Done!\n");
	initializeTimer();
	initializeKeyboardDriver();
	initializeSerialPorts();
	printf("  * Installing system services... ");
	installInt80();
	printf("Done!\n  * P0 forking a new child... ");
	kfork();
	printf("Done!\n  * P0 switching to P1...\n");
	tswitch();
	printf("\n-----------------------------------------------------\n");
	printf("\n  * P0 resumed: All processes dead! Woo Hoo!\n");
}

// Initializes the processes and sets P0 to running
void initializeProcesses()
{
	int i, j;
	
	// Initialize the queues to zero
	freeQueue.size = 0;
	freeQueue.top = 0;
	readyQueue.size = 0;
	readyQueue.top = 0;
	sleepQueue.size = 0;
	sleepQueue.top = 0;
	
	// Prepare P0 for running
	running = &processes[0];
	running->processID = 0;
	running->priority = 0;
	running->deathCry = deathCries[0];
	running->status = READY;
	strcpy(running->name, processNames[0]);
	
	// Set up the rest of the processes as free
	for (i = 1; i < NUM_PROCS; ++i)
	{
		processes[i].processID = i;
		processes[i].priority = 1;
		processes[i].status = FREE;
		processes[i].deathCry = deathCries[i % 4];
		strcpy(processes[i].name, processNames[i]);
		enqueue(&processes[i], &freeQueue);
	}
	
	// Clear all processes file descriptors
	for (i = 0; i < NUM_PROCS; ++i)
	{
		for (j = 0; j < NUM_FILE_DESC; ++j)
		{
			processes[i].fileDescriptors[j] = 0;
		}
	}
}
